package com.itheima.ui;

import com.hzheima.game.GameJPanel;
import com.hzheima.util.ImageUtil;
import com.itheima.config.AppConfig;
import com.itheima.entity.Ball;
import com.itheima.entity.Bullet;
import com.itheima.entity.Plan;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class BallFightPanel extends GameJPanel {
    BufferedImage img;
    BufferedImage money;
    BufferedImage st;
    BufferedImage ed;
    Plan plan;
    Bullet bullet;
    private boolean gameover;
    private int number = 0;
    private int level = 1;


    public BallFightPanel() {
        //设置背景颜色
        setBackground(Color.PINK);
        //加载图片，找到图片
        img = ImageUtil.getImg("BG.png");
        money = ImageUtil.getImg("money.png");
        st = ImageUtil.getImg("st.png");
        ed = ImageUtil.getImg("ed.png");
        plan = new Plan();
        bullet = new Bullet(plan.getX(), plan.getY());
    }

    //绘制背景图片
    @Override
    public void paint(Graphics g) {
        //Graphics g  相当于画笔
        super.paint(g);
        //通过画笔把空参构造里加载的背景图片绘制到面板中
        g.drawImage(img, 0, 0, 512, 768, null);
        //画金币图标
        g.drawImage(money, 300, 10, 30, 30, null);

        //分数
        g.setFont(new Font("楷体", Font.BOLD, 25));

        //设置字体颜色
        g.setColor(Color.white);
        g.drawString("分数:" + number, 30, 30);
        g.drawString("历史最高：0.00K", 300, 60);
        g.drawString("金币：0.00K", 340, 32);

        //画关卡名
        g.setFont(new Font("楷体", Font.PLAIN, 30));
        g.drawString("关卡:" + level, 25, 60);

        //绘制左括号
        g.drawImage(st, 20, 80, 5, 25, null);
        g.drawImage(st, 20, 80, 5, 25, null);

        //设置灰色
        g.setColor(Color.gray);
        for (int i = 0; i < 30; i++) {
            g.fillRect(30 + i * (10 + 5), 80, 10, 25);
        }

        //设置蓝色
        g.setColor(Color.cyan);
        for (int i = 0; i < number; i++) {
            g.fillRect(30 + i * (10 + 5), 80, 10, 25);
        }
        //绘制右括号
        g.drawImage(ed, 512 - 30, 80, 5, 25, null);

        //画飞机
        plan.draw(g);

        //画子弹
        ArrayList<Bullet> bullets = plan.getBullets();
        for (int i = 0; i < bullets.size(); i++) {
            Bullet bullet = bullets.get(i);
            bullet.draw(g);
        }
        //画球
        for (int i = 0; i < balls.size(); i++) {
            Ball ball = balls.get(i);
            ball.draw(g);
        }
        //游戏结束了绘制提示
        if (gameover) {
            //设置画笔为红色
            g.setColor(Color.red);
            Graphics2D g2d = (Graphics2D) g;
            //设置透明度,绘制红色矩形
            AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.42f);
            g2d.setComposite(alphaComposite);
            g2d.fillRect(0, 200, AppConfig.APP_WIDTH, 300);


            //透明度设置回来，然后设置成白色
            AlphaComposite alphaComposite1 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
            g2d.setComposite(alphaComposite1);

            g.setColor(Color.white);
            g.setFont(new Font("楷体", Font.BOLD, 30));
            g.drawString("游戏结束", 180, 240);

            g.setColor(Color.yellow);
            g.drawString("本次得分：0", 150, 300);
            g.drawString("获得金币：", 100, 370);
            g.drawImage(money, 250, 340, 40, 40, null);
            g.drawString("0.00k", 300, 370);

            g.setColor(Color.white);
            g.drawString("{按F1重新开始游戏}", 80, 480);

        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        //判断是A按下了还是D按下了
        if (e.getKeyCode() == 'A' && !gameover) {
            //说明A被按下了  飞机向左移动一次
            plan.moveToLeft();
        } else if (e.getKeyCode() == 'D' && !gameover) {
            //说明D被按下了   飞机向右移动一次
            plan.moveToRight();
        } else if (e.getKeyCode() == 'W' && !gameover) {
            //说明W被按下了   飞机向右移动一次
            plan.moveToForward();
        } else if (e.getKeyCode() == 'S' && !gameover) {
            //说明S被按下了   飞机向右移动一次
            plan.moveToBackward();
        } else if (e.getKeyCode() == 112 && gameover) {
            //游戏重新开始
            gameover = false;
            //小球清空
            balls.clear();
            //飞机重新创建
            plan = new Plan();

            number = 0;
            level = 1;
        }
        //重新绘制
        repaint();
    }

    //用于保存所有当前存在的球
    ArrayList<Ball> balls = new ArrayList<>();
    int count = 0;

    @Override
    public void run() {
        //每隔300ms发射一颗子弹
        if (!gameover) {
            plan.shoot();
            //创建球
            createBall();
            //移动球
            moveBall();
            //判断球是否被打中
            isShootBall();
            //判断飞机是否碰撞
            //isCrash();
        }
        //重绘
        repaint();
    }

    private void isCrash() {
        //遍历所有的球，拿每一个球和飞机做判断
        for (int i = balls.size() - 1; i >= 0; i--) {
            Ball ball = balls.get(i);
            if (plan.isCrash(ball)) {
                //说明撞上  让球消失，
                balls.remove(ball);
                gameover = true;
            }
        }

    }

    //让所有球移动
    private void moveBall() {
        for (int i = 0; i < balls.size(); i++) {
            Ball ball = balls.get(i);
            ball.move();
        }
    }

    // 创建球
    private void createBall() {
        //每300ms创建一个球
        count++;
        if (count % 10 == 0) {
            //最多创建两个
            if (balls.size() < AppConfig.BALL_MAX_CREATE_COUNT) {
                balls.add(new Ball());
            }
            count = 0;
        }
    }

    private void isShootBall() {
        //遍历所有的球
        for (int i = balls.size() - 1; i >= 0; i--) {
            Ball ball = balls.get(i);
            //判断当前遍历到的球和每颗子弹是否碰撞
            ArrayList<Bullet> bullets = plan.getBullets();
            for (int j = bullets.size() - 1; j >= 0; j--) {
                Bullet bullet = bullets.get(j);
                //shootBy 可以判断是否和子弹碰撞了，如果碰撞了，血量减少
                if (ball.shootBy(bullet)) {
                    //如果碰撞了就做相应的处理
                    //子弹消失
                    bullets.remove(bullet);
                    //判断血量是否为0 ，如果为0，球也消失
                    if (ball.getBlood() <= 0) {
                        balls.remove(ball);
                        number ++;
                        if (number != 0 && number % 30 == 0) {
                            level++;
                            number = 0;
                        }
                    }
                    //判断球的血量是否为原血量的一半，如果是就分裂
                    if (ball.getBlood() <= ball.getInitBlood() / 2) {
                        //球应该分裂
                        ArrayList<Ball> list = ball.split();
                        //从集合中删除当前球，然后把分裂出来的球添加到集合中
                        balls.remove(ball);
                        balls.addAll(list);
                    }
                }
            }
        }
    }
}
